package org.hawk.gwt.ppc;

import java.io.IOException;

import org.hawk.gwt.ppc.reflect.LangPreprocessor;
import org.hawk.gwt.ppc.reflect.MetadataProcessor;
import org.hawk.gwt.ppc.reflect.ReflectionCallsProcessor;

/**
 * Creates configured environment for the internal usage.
 * 
 * @author alex.bereznevatiy@gmail.com
 */
public class Environment {
	private static Environment instance;

	private Environment() {
	}

	/**
	 * @return <i></i> singleton instance of {@link Environment}
	 */
	public static Environment getInstance() {
		if (instance == null) {
			instance = new Environment();
		}
		return instance;
	}

	private Configuration configuration;

	/**
	 * @return {@link Configuration} for this {@link Environment}
	 */
	public Configuration getConfiguration() {
		if (configuration == null) {
			// for testing purposes
			this.configuration = new CmdArgs(new String[0]);
		}
		return configuration;
	}

	/**
	 * Configure current {@link Environment} using command line arguments.
	 * 
	 * @param argsProcessor
	 * @throws IOException
	 */
	void configure(Configuration argsProcessor) throws IOException {
		this.configuration = argsProcessor;
		
		ProcessingUnitsManager manager = ProcessingUnitsManager.getInstance();
		manager.configure();
		if (argsProcessor.get(Configuration.REFLECTION_PARAMETER) != null) {
			manager.addProcessingUnit(new LangPreprocessor());
			manager.addProcessingUnit(new MetadataProcessor());
		}
		manager.addProcessingUnit(new ReflectionCallsProcessor());
	}

	/**
	 * Releases all the resources that should be released after compilation.
	 */
	void dispose() {
		if (!configuration.get(Configuration.KEEP_PREPROCESSED_SOURCES_PARAMETER, false)) {
			ProcessingUnitsManager.getInstance().dispose();
		}
	}
}
